package com.xbongbong.paas.service.workflow.log.impl;

import com.alibaba.fastjson.JSONArray;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.service.workflow.log.WorkFlowTaskLogService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.DateDiffUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskLogEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskLogItemEntity;
import com.xbongbong.paas.config.enums.WorkflowTaskLogStatusEnum;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.WorkflowTaskLogItemModel;
import com.xbongbong.workflow.model.WorkflowTaskLogModel;
import com.xbongbong.paas.pojo.workflow.WorkflowTaskLogPojo;
import com.xbongbong.paas.pojo.workflow.task.dto.WorkFlowTaskLogDetailDTO;
import com.xbongbong.paas.pojo.workflow.task.dto.WorkFlowTaskLogListDTO;
import com.xbongbong.paas.pojo.workflow.task.vo.WorkFlowTaskLogListVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 胡国军
 * @date 2021/05/25 14:59
 */
@Service("workFlowTaskLogService")
public class WorkFlowTaskLogServiceImpl implements WorkFlowTaskLogService {

    @Resource
    private WorkflowTaskLogModel workflowTaskLogModel;
    @Resource
    private WorkflowTaskLogItemModel workflowTaskLogItemModel;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private ProFormHelp proFormHelp;

    @Override
    public WorkFlowTaskLogListVO list(WorkFlowTaskLogListDTO workFlowTaskLogListDTO) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", workFlowTaskLogListDTO.getCorpid());
        param.put("del", 0);
        param.put("status", workFlowTaskLogListDTO.getStatus());
        param.put("formId", workFlowTaskLogListDTO.getFormId());
        JSONArray triggerTime = workFlowTaskLogListDTO.getTriggerTime();
        if (triggerTime != null && triggerTime.size() > 0) {
            param.put("addTimeStart", triggerTime.getLong(0));
            if (triggerTime.size() > 1) {
                param.put("addTimeEnd", triggerTime.getLong(1));
            }
        }
        param.put(ParameterConstant.PAGE, workFlowTaskLogListDTO.getPage());
        param.put("orderByStr", "add_time desc");
        if (StringUtil.isNotEmpty(workFlowTaskLogListDTO.getLinkKey())) {
            param.put("linkKey", workFlowTaskLogListDTO.getLinkKey());
        }
        PageHelper pageHelper = PageHelperUtil.getPageHelper(param, workflowTaskLogModel, workFlowTaskLogListDTO.getPageSize());
        List<WorkflowTaskLogEntity> workflowTaskLogEntityList = (List<WorkflowTaskLogEntity>) PageHelperUtil.getEntityList(param, pageHelper, workflowTaskLogModel);

        List<Long> formIdIn = new ArrayList<>();
        List<Long> workOrderFormIdIn = new ArrayList<>();
        workflowTaskLogEntityList.forEach(workflowTaskLog -> {
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), workflowTaskLog.getBusinessType())) {
                workOrderFormIdIn.add(workflowTaskLog.getFormId());
            } else {
                formIdIn.add(workflowTaskLog.getFormId());
            }
        });

        Map<Long, PaasFormEntity> paasFormMap = proFormHelp.getFormMap(formIdIn, workFlowTaskLogListDTO.getCorpid(), DelEnum.NORMAL.getDel());
        Map<Long, WorkOrderFormEntity> workOrderFormMap = proFormHelp.getWorkOrderFormMap(workOrderFormIdIn, workFlowTaskLogListDTO.getCorpid(), DelEnum.NORMAL.getDel());

        List<WorkflowTaskLogPojo> workflowTaskLogList = new ArrayList<>();
        for (WorkflowTaskLogEntity workflowTaskLogEntity : workflowTaskLogEntityList) {
            WorkflowTaskLogPojo workflowTaskLogPojo = new WorkflowTaskLogPojo();
            workflowTaskLogPojo.setStatus(WorkflowTaskLogStatusEnum.getByCode(workflowTaskLogEntity.getStatus()).getTaskMemo());
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), workflowTaskLogEntity.getBusinessType())) {
                workflowTaskLogPojo.setForm(workOrderFormMap.getOrDefault(workflowTaskLogEntity.getFormId(), new WorkOrderFormEntity()).getName());
            } else {
                workflowTaskLogPojo.setForm(paasFormMap.getOrDefault(workflowTaskLogEntity.getFormId(), new PaasFormEntityExt()).getName());
            }
            if (!Objects.equals(workflowTaskLogEntity.getStatus(), WorkflowTaskLogStatusEnum.PASS.getType())) {
                workflowTaskLogPojo.setContent(workflowTaskLogEntity.getContent());
            }
            workflowTaskLogPojo.setAddTime(DateTimeUtil.getStringEpochSecond(workflowTaskLogEntity.getAddTime(), DateTimeUtil.SDF));
            workflowTaskLogPojo.setExitTime(DateTimeUtil.getStringEpochSecond(workflowTaskLogEntity.getExitTime(), DateTimeUtil.SDF));
            long timeConsume;
            if (workflowTaskLogEntity.getExitTime() == null || workflowTaskLogEntity.getExitTime() == 0) {
                timeConsume = DateTimeUtil.getInt() - workflowTaskLogEntity.getAddTime();
            } else {
                timeConsume = workflowTaskLogEntity.getExitTime() - workflowTaskLogEntity.getAddTime();
            }
            workflowTaskLogPojo.setTimeConsume(DateDiffUtil.formatInterval(timeConsume));
            workflowTaskLogPojo.setTaskId(workflowTaskLogEntity.getTaskId());
            workflowTaskLogPojo.setWorkflowTaskLogId(workflowTaskLogEntity.getId());
            workflowTaskLogPojo.setStatusCode(workflowTaskLogEntity.getStatus());
            workflowTaskLogPojo.setLinkKey(Objects.isNull(workflowTaskLogEntity.getLinkKey()) ? "" : workflowTaskLogEntity.getLinkKey());
            workflowTaskLogList.add(workflowTaskLogPojo);
        }

        WorkFlowTaskLogListVO workFlowTaskLogListVO = new WorkFlowTaskLogListVO();
        workFlowTaskLogListVO.setPageHelper(pageHelper);
        workFlowTaskLogListVO.setWorkflowTaskLogList(workflowTaskLogList);
        return workFlowTaskLogListVO;
    }

    @Override
    public WorkFlowTaskLogListVO detail(WorkFlowTaskLogDetailDTO workFlowTaskLogDetailDTO) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", workFlowTaskLogDetailDTO.getCorpid());
        param.put("del", 0);
        param.put("workflowTaskLogId", workFlowTaskLogDetailDTO.getWorkflowTaskLogId());
        List<WorkflowTaskLogItemEntity> workflowTaskLogItemEntityList = workflowTaskLogItemModel.findEntitys(param);

        List<Long> workflowNodeIdIn = new ArrayList<>();
        workflowTaskLogItemEntityList.forEach(workflowTaskLogItem -> workflowNodeIdIn.add(workflowTaskLogItem.getWorkflowNodeId()));

        param.clear();
        param.put("corpid", workFlowTaskLogDetailDTO.getCorpid());
        param.put("del", 0);
        param.put("idIn", workflowNodeIdIn);
        List<WorkflowNodeEntity> workflowNodeEntityList = workflowNodeModel.findEntitys(param);
        Map<Long, WorkflowNodeEntity> workflowNodeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        workflowNodeEntityList.forEach(workflowNodeEntity -> workflowNodeMap.put(workflowNodeEntity.getId(), workflowNodeEntity));

        List<WorkflowTaskLogPojo> workflowTaskLogList = new ArrayList<>();
        workflowTaskLogItemEntityList.forEach(workflowTaskLogItem -> {
            WorkflowTaskLogPojo workflowTaskLogPojo = new WorkflowTaskLogPojo();
            workflowTaskLogPojo.setStatus(WorkflowTaskLogStatusEnum.getByCode(workflowTaskLogItem.getStatus()).getMemo());
            workflowTaskLogPojo.setNode(workflowNodeMap.getOrDefault(workflowTaskLogItem.getWorkflowNodeId(), new WorkflowNodeEntity()).getName());
            workflowTaskLogPojo.setContent(workflowTaskLogItem.getContent());
            workflowTaskLogPojo.setAddTime(DateTimeUtil.getStringEpochSecond(workflowTaskLogItem.getAddTime(), DateTimeUtil.SDF));
            workflowTaskLogPojo.setExitTime(DateTimeUtil.getStringEpochSecond(workflowTaskLogItem.getExitTime(), DateTimeUtil.SDF));
            workflowTaskLogPojo.setStatusCode(workflowTaskLogItem.getStatus());
            workflowTaskLogPojo.setNodeType(workflowTaskLogItem.getNodeType());
            workflowTaskLogList.add(workflowTaskLogPojo);
        });

        WorkFlowTaskLogListVO workFlowTaskLogListVO = new WorkFlowTaskLogListVO();
        workFlowTaskLogListVO.setWorkflowTaskLogList(workflowTaskLogList);

        WorkflowTaskLogEntity workflowTaskLogEntity = workflowTaskLogModel.getByKey(workFlowTaskLogDetailDTO.getWorkflowTaskLogId(), workFlowTaskLogDetailDTO.getCorpid());
        if (Objects.nonNull(workflowTaskLogEntity)) {
            WorkflowTaskLogPojo workflowTaskLogPojo = new WorkflowTaskLogPojo();
            workflowTaskLogPojo.setStatusCode(workflowTaskLogEntity.getStatus());
            workflowTaskLogPojo.setStatus(WorkflowTaskLogStatusEnum.getByCode(workflowTaskLogEntity.getStatus()).getTaskMemo());
            PaasFormEntity paasFormEntityExt = proFormHelp.getPaasForm(workflowTaskLogEntity.getFormId(), workflowTaskLogEntity.getBusinessType(), workFlowTaskLogDetailDTO.getCorpid());
            if (paasFormEntityExt != null) {
                workflowTaskLogPojo.setForm(paasFormEntityExt.getName());
            }
            workFlowTaskLogListVO.setWorkflowTaskLogInfo(workflowTaskLogPojo);
        }
        return workFlowTaskLogListVO;
    }

}
